
#include <BPainter>
#include <BRender>
#include <BViewer>
#include <BScene>
#include <BPhysics>
#include <BCone>
#include <BCube>
#include <BImage>
#include <BMaterial>
#include <BReadWrite>

#include "SliderHandler.h"

SliderHandler::SliderHandler()
{
	_lengthText = new BTextual();
	_lengthText->setColor(200, 0, 0);
	_lengthText->setCullback(false);
	_lengthText->setLighting(false);
	_lengthText->setPolyMode(Poly_Fill);
	_lengthText->setGlyphSize(0.3);

	BImage* image = ReadFile<BImage>("data/image/whitemetal_diffuse.jpg");

	_nodeA = new BNode("nodeA");
	{
		BPhysics* physics = new BPhysics();
		physics->setMass(10.0);
		_nodeA->setPhysics(physics);

		BCube* cube = new BCube(4, 12);
		cube->setColor(100, 200, 255);
		_nodeA->addShape(cube);

	}

	_nodeB = new BNode("nodeB");
	{
		BPhysics* physics = new BPhysics();
		physics->setMass(1.0);
		_nodeB->setPhysics(physics);

		BCone* cone = new BCone(0.5, 2, 24, 10);
		cone->setTexture(image);
		cone->setColor(200, 100, 0);
		_nodeB->addShape(cone);
	}

	BVector pointA = _nodeA->space().max();
	BVector end = BVector(10, 10, 0);
	BVector pointB(0, 0, _nodeB->space().max().z());
	BVector axisB(0, 0, 1);
	_sliderConstraint = new BSliderConstraint(_nodeA, pointA, _nodeB, pointB);

	_sliderConstraint->setAngleLimit(0, PI / 6);
	_sliderConstraint->setName("Slider");
}
SliderHandler::~SliderHandler()
{

}

void SliderHandler::attached(BViewer* viewer)
{
	BScene* dscene = viewer->scene();
	_nodeA->setPosition(0, 0, 5);
	_nodeB->setPosition(2, 2, 5);
	dscene->insert(_nodeA);
	dscene->insert(_nodeB);
	dscene->insert(_sliderConstraint);
	_lengthText->setFont(viewer->font());
	viewer->scene()->insert(_lengthText);
	this->emit("edit-constraint", _sliderConstraint);
}
void SliderHandler::detached(BViewer* viewer)
{
	BScene* dscene = viewer->scene();
	dscene->remove(_nodeA);
	dscene->remove(_nodeB);
	dscene->remove(_sliderConstraint);
	viewer->scene()->remove(_lengthText);
}

void SliderHandler::paint(BPainter& painter)
{
	BViewer* viewer = this->viewer();
	painter.setLineWidth(10);
	painter.setColor(BColor(0, 1, 0));
	painter.drawRect(10, 10, viewer->width() - 20, viewer->height() - 20);
}
void SliderHandler::render(BRender& render)
{
	render.setLighting(false);
	render.setDepthTest(false);
	render.setLineSmooth(true);
	render.setLineWidth(1);
	
	if (_sliderConstraint)
	{
		BLine line;
		{
			const BMatrix& matrixA = _sliderConstraint->nodeA()->matrix();
			const BRealRange& linearLimit = _sliderConstraint->linearLimit();
			line.setBegin((_sliderConstraint->pointA() + _sliderConstraint->axisA() * linearLimit.min()) * matrixA);
			line.setEnd((_sliderConstraint->pointA() + _sliderConstraint->axisA() * linearLimit.max()) * matrixA);
		}
		render.setColor(255, 255, 255);
		render.drawLine(line);

		BVector pointB = _sliderConstraint->pointB() * _sliderConstraint->nodeB()->matrix();
		BVector offset(0, 0, 2);
		BReal length = line.ratio(pointB);
		BString lengthStr(length, 3);
		_lengthText->setText(lengthStr);
		_lengthText->setDown(0, 0, -1);
		_lengthText->setRight(line.direct());
		_lengthText->setPosition((line.begin() + pointB) / 2 + offset);

		BQuad quad = _lengthText->quad() * _lengthText->matrix();
		render.drawQuad(quad);

		BVector leftCenter = (quad.a() + quad.b()) / 2;
		BVector rightCenter = (quad.c() + quad.d()) / 2;
		BVector pointA0 = line.begin() + offset;
		BVector pointB0 = pointB + offset;
		render.setLineWidth(1);
		render.setLineStipple(0xF0F0);
		render.setColor(255, 255, 255);
		render.drawLine(line.begin(), pointA0);
		render.drawLine(pointA0, leftCenter);
		render.drawLine(pointB, pointB0);
		render.drawLine(pointB0, rightCenter);
		return;
	}

}
